/******************************************************************************

    Simple Authentication and Authorisation System (SAAS)

    common.c

    Copyright (C) 2011  Josh Goes


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you require a mailing address for this software, please send your
    mail to the following address:
        SAAS
        GPO Box 2973
        BRISBANE QLD 4001
        AUSTRALIA

******************************************************************************/


#include "saas.h"
#include "tests.h"

#include <unistd.h>
#include <string.h>
#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>


uint16_t  saas_get_opts( struct st_saas_test_opt *opts , int argc , char **argv )
{
	struct st_saas_test_opt  *st  = opts;
	char  index[1024];
	struct option gol_opts[64];
	uint32_t  pos = 0;

	memset( index , 0 , sizeof( index ) );

	// run through each option and start building a getopt_long() compatible
	// option list.
	while ( st->long_name != NULL )
	{
		gol_opts[pos].name = st->long_name;
		gol_opts[pos].has_arg = st->has_arg;
		gol_opts[pos].flag = NULL;
		if ( st->short_name != NULL )
			gol_opts[pos].val = st->short_name[0];
		else
			gol_opts[pos].val = 0;

		if ( st->short_name != 0 )
		{
			strcat( index , st->short_name);
			if ( st->has_arg != 0 )
				strcat( index , ":" );
		}
		st++;
		pos++;
	}


	// and now we get all the options thanks to glibc
	int c;
	int opt_idx;
	while ( 1 )
	{
		c = getopt_long( argc , argv , index , gol_opts , &opt_idx );

		// no more hosts.
		if ( c == -1 )
			break;

		if ( c == '?' )
			continue;

		// and now we run through all the options in our struct, and
		// raise a callback for the right one.
		st = opts;
		while ( st->long_name != NULL )
		{
			if ( strchr( st->short_name , c ) != NULL )
			{
				if ( st->callback != NULL )
					st->callback( st->long_name , optarg );

				if ( st->var != NULL )
				{
					if ( st->var_type == SAAS_TEST_VAR_TYPE_STR )
					{
						if ( st->var_str_val == NULL )
							strncpy( st->var , optarg , st->var_str_len );
						else
							strncpy( st->var , st->var_str_val , st->var_str_len );
					}
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_UINT8 )
						*( (uint8_t *) st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_SINT8 )
						*( (int8_t *)  st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_UINT16 )
						*( (uint16_t *) st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_SINT16 )
						*( (int16_t *)  st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_UINT32 )
						*( (uint32_t *) st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_SINT32 )
						*( (int32_t *)  st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_UINT64 )
						*( (uint64_t *) st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
					else if ( st->var_type == SAAS_TEST_VAR_TYPE_SINT64 )
						*( (int64_t *)  st->var ) = ( st->var_int_val == 0 ) ? atoi( optarg ) : st->var_int_val;
				}
				break;
			}
			st++;
		}
	}

	return SAAS_OP_SUCCESS;
}



